#ifndef SVL_TArrayFix_H
#define SVL_TArrayFix_H

#include "svl.h"

namespace svl {

template <class T, int maxCount>
struct TArrayPtrFix : public TDebug {
	TArrayPtrFix(): count(0) {}
	//
	void AddLast( T elem ){
		if( count < maxCount ){
			Array[count] = elem;
			++count;
		}
		else
			Except("AddLast[else]");
	}
	
	void AddFirst( T elem ){
		if( count < maxCount ){
		  ::memmove(
            Array + 1,
		    Array,
            count * sizeof(T)
          );
		  Array[0] = elem;
		  ++count;
		}
		else
			Except("AddFirst[else]");
	}

	void DeleteLast() {
    if (count > 0) {
      count--;
      return;
    }
	  Except("DeleteLast");
	}

	void Delete(int num) {
	  if (num >= 0 && num < count) {
        if (num+1 == count) {
          count--;
          return;
        }

        ::memmove(
          Array + (num),
		  Array + (num+1),
          (count - (num+1))*sizeof(T)
        );

        count--;
        return;
	  }
		
	  Except("Delete");
	}
	
	T Get(int num) {
		if( num >= 0 && num < count )
			return Array[num];
		Except("Get[else]");
		static T t; return t;
	}
	
	T *GetCellPtr(int num) {
		if( num >= 0 && num < count )
			return Array+num;
		Except("GetCellPtr[else]");
		return NULL;
	}
	
	void Clear()   { count = 0; }
	int Count()    { return count; }
	int MaxCount() { return sizeof(Array)/sizeof(T); }

	void MoveToEnd( TArrayPtrFix &To ){
		if( count <= To.MaxCount() - To.count ){
			::memmove(
				To.Array + To.count,
				Array,
				count*sizeof(T)
			);
			To.count += count;
			count = 0;
		}
		else
			Except("MoveToEnd[else]");
	}
	
  bool Search(T elem) {
    for (int N = 0; N < count; N++) {
      if (Array[N] == elem) {
        return true;
      }
    }
    return false;
  }

protected:
	T Array[maxCount];
	int count;
	svl_Except;
};


///////////////////////////////////////////////////////////////////////////////
}

#endif